package org.xmap.ui.control;

import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

import org.xmap.ui.ViewManager;
import org.xmap.ui.base.Window;

public final class CircleGuage extends Window {

    /**
     * 小圆的数目
     */
    private int circleNum;
    /**
     * 小圆所在矩形的左坐标
     */
    private int[] circlePosX;
    /**
     * 小圆所在矩形的上坐标
     */
    private int[] circlePosY;
    /**
     * 小圆的半径
     */
    private int circleRadius;
    /**
     * 小圆动画帧组图
     */
    private Image[] circleImage;
    /**
     * 控制等待进度动画
     */
    private int index;
    /**
     * 滚动圈的颜色。
     */
    private int color;
    /**
     * 该变量用于调整图片的边缘，alpha低于这个值的像素将不可见。
     */
    private int adjust;

    /**
     *
     * @param leftUpX int x坐标
     * @param leftUpY y坐标
     * @param width 宽度
     * @param circleRadius 小圆的半径
     * @param color 颜色
     */
    public CircleGuage(int leftUpX, int leftUpY, int width, int circleRadius, int color) {
        super(leftUpX, leftUpY, width, width);
        if (circleRadius > width >> 1) {
            circleRadius = width >> 1;
        }
        this.circleRadius = circleRadius;
        this.index = 0;
        this.color = color;
        this.adjust = 0;
        this.countCircleNum();
        this.countCirclePos();
        this.setAlphaCircleImage();
    }

    public void setRect(int leftUpX, int leftUpY, int width) {
        super.setRect(leftUpX, leftUpY, width, width);
        if (circleRadius > width >> 1) {
            circleRadius = width >> 1;
        }
        this.countCircleNum();
        this.countCirclePos();
        this.setAlphaCircleImage();
    }

    public void setColor(int color) {
        this.color = color;
        this.setAlphaCircleImage();
    }

    public int getColor() {
        return this.color;
    }

    public void setAdjust(int adjust) {
        this.adjust = adjust;
    }

    public void resetIndex() {
        this.index = 0;
    }

    public void draw(Graphics g) {
        for (int i = 0; i < circleNum; i++) {
            int temp = i + index;
            if (temp >= circleNum) {
                temp -= circleNum;
            }
            g.drawImage(circleImage[temp], circlePosX[i], circlePosY[i], Graphics.HCENTER | Graphics.VCENTER);
        }
    }

    public void update() {
        index--;
        if (index < 0) {
            index = circleNum - 1;
        }

//        index++;
//        if (index > circleNum - 1) {
//            index = 0;
//        }
        ViewManager.instance.requestRepaint();
    }

    /**
     * 获取小圆带alpha渐变的组图
     */
    private void setAlphaCircleImage() {
        // 计算小圆颜色渐变值
        int[] colorShade = new int[this.circleNum];
        for (int i = colorShade.length - 1; i >= 0; i--) {
            int alpha = 255 - 255 * (i + 1) / colorShade.length;
            colorShade[colorShade.length - i - 1] = ((alpha << 24) | (this.color & 0x00ffffff));
        }

        // 得到有alpha值的小圆图像
        if (this.circleImage == null) {
            this.circleImage = new Image[this.circleNum];
        }
        int radius = (this.circleRadius << 1) + 1;
        Image img = Image.createImage(radius, radius);
        int[] data = new int[radius * radius << 4];
        for (int i = this.circleNum - 1; i >= 0; i--) {
            this.circleImage[i] = this.getAlphaImage(img, data, colorShade[i]);
        }
    }

    /**
     * 计算圆圈的个数
     */
    private void countCircleNum() {
        if (this.getRect().width < 20) { // 当区域宽度小于20时，圆圈个数为8
            this.circleNum = 8;
        } else {
            if (this.getRect().width > (this.circleRadius << 2)) {
                this.circleNum = 12;
            } else {
                this.circleNum = 8;
            }
        }
    }

    /**
     * 获取小圆动画组坐标
     * @return 获取到坐标值返回true
     */
    private boolean countCirclePos() {

        if (this.circleRadius <= 0) {
            return false;
        }

        this.circlePosX = new int[this.circleNum];
        this.circlePosY = new int[this.circleNum];

        int midX = this.getRect().width >> 1;
        int midY = this.getRect().width >> 1;

        int rectRadius = this.circleRadius << 1;
        if (rectRadius > (this.getRect().width >> 1) - this.circleRadius) {
            rectRadius = (this.getRect().width >> 1) - this.circleRadius;
        }

        int[] sinBeta = null;
        int[] cosBeta = null;

        if (this.circleNum == 12) { // 画12个小圆
            int[] sinBeta2 = {1024, 887, 512, 0, -512, -887, -1024, -887, -512, 0, 512, 887};
            int[] cosBeta2 = {0, 512, 887, 1024, 887, 512, 0, -512, -887, -1024, -887, -512};
            sinBeta = sinBeta2;
            cosBeta = cosBeta2;
        } else { // 画8个小圆
            int[] sinBeta2 = {1024, 724, 0, -724, -1024, -724, 0, 724};
            int[] cosBeta2 = {0, 724, 1024, 724, 0, -724, -1024, -724};
            sinBeta = sinBeta2;
            cosBeta = cosBeta2;
        }

        for (int i = 0; i < this.circleNum; i++) {
            if (sinBeta[i] > 0) {
                this.circlePosX[i] = midX + ((rectRadius * sinBeta[i]) >> 10);
            } else {
                this.circlePosX[i] = midX - (( -rectRadius * sinBeta[i]) >> 10);
            }
            if (cosBeta[i] > 0) {
                this.circlePosY[i] = midY + ((rectRadius * cosBeta[i]) >> 10);
            } else {
                this.circlePosY[i] = midY - (( -rectRadius * cosBeta[i]) >> 10);
            }
        }
        return true;
    }

    private Image getAlphaImage(Image img, int[] data, int color) {
        Graphics g = img.getGraphics();
        int width = img.getWidth();

        g.setColor(color);
//        g.fillRect(0, 0, width, width);
        g.fillArc(0, 0, width, width, 0, 360);

        img.getRGB(data, 0, width, 0, 0, width, width);

        for (int y = 0; y < width; y++) {
            for (int x = 0; x < width; x++) {
                data[x + y * width] = this.getCircleAlphaColor(x - this.circleRadius, y - this.circleRadius, this.circleRadius, color);
//                int alpha = ((data[x + y * width] & 0xff000000) >> 24);
//                if (alpha < 0) {
//                    alpha += 256;
//                }
//                if (alpha < 10) {
//                    System.out.print(alpha + "    ");
//                } else if (alpha < 100) {
//                    System.out.print(alpha + "   ");
//                } else {
//                    System.out.print(alpha + "  ");
//                }
            }
//            System.out.println();
        }

        img = Image.createRGBImage(data, width, width, true);
        return img;
    }

    /**
     * 改变小圆图像上的像素点alpha值
     *
     * @param x 相对于圆心的x坐标
     * @param y 相对于圆心的y坐标
     * @param r 圆的半径
     * @param color 带alpha通道的颜色
     * @return 改变alpha后的像素颜色
     */
    private int getCircleAlphaColor(int x, int y, int r, int color) {
        int alpha = (color >> 24) & 0xff;
//        alpha = alpha - alpha * (x * x + y * y) / (r * r) - 80; // alpha为二次曲线衰减
        alpha = alpha - alpha * (x * x + y * y) / (r * r); // alpha为二次曲线衰减
        if (alpha < adjust) {
            alpha = 0;
        }
        color &= 0x00ffffff;
        color |= (alpha << 24);
        return color;
    }
}
